import Singleton from "../../framework/scripts/base/Singleton"
import EventMgr from "../../framework/scripts/manager/EventMgr"
import PanelMgr from "../../framework/scripts/view/PanelMgr"
import GameConstants from "../GameConstants"
import Wait from "../core/Wait"


// 场景加载参数
interface ISceneLoadArg {
    stopMusic?: boolean     //是否停止音乐(默认停止)
    stopEffect?: boolean    //是否停止音效
    onLoaded?: Function     //加载成功回调
}


export default class SceneMgr extends Singleton {
    public static get inst() {
        return this.getInstance<SceneMgr>()
    }


    private _sceneName: string
    public get sceneName() { return this._sceneName }

    private _loadScenes: Map<string, boolean> = new Map()


    public preloadScenes(sceneNames: string[]) {
        let loadNum = 0

        sceneNames.forEach(sceneName => {
            this.preloadScene(sceneName, (err: Error) => {
                if (err) {
                    cc.error('SceneMgr.preloadScenes [%s] err:', sceneName, err)
                    return
                }

                loadNum++
                if (loadNum == sceneNames.length) {
                    EventMgr.emit(GameConstants.event.ScenePreloadOk)
                }
            })
        })
    }

    public preloadScene(sceneName: string, onLoaded?: (error: Error) => void) {
        if (this._loadScenes.get(sceneName)) {
            onLoaded && onLoaded(null)
            return
        }

        cc.director.preloadScene(sceneName, null, (err: Error) => {
            if (err && !onLoaded) {
                cc.error('SceneMgr.preloadScene [%s] err:', sceneName, err)
                return
            }

            if (!err) {
                this._loadScenes.set(sceneName, true)
            }

            onLoaded && onLoaded(err)
        })
    }

    public loadScene(sceneName: string, loadArg?: ISceneLoadArg) {
        if (this._loadScenes.get(sceneName)) {
            this.loadSceneReal(sceneName, loadArg)
            return
        }

        Wait.show()
        this.preloadScene(sceneName, (err: Error) => {
            Wait.hide()

            if (err) {
                cc.error('SceneMgr.loadScene preloadScene [%s] err:', sceneName, err)
                return
            }

            this.loadSceneReal(sceneName, loadArg)
        })
    }

    public loadSceneReal(sceneName: string, loadArg?: ISceneLoadArg) {
        if (loadArg?.stopMusic || loadArg?.stopMusic == undefined) {
            cc.audioEngine.stopMusic()
        }
        if (loadArg?.stopEffect) {
            cc.audioEngine.stopAllEffects()
        }

        PanelMgr.hideAll()

        cc.director.loadScene(sceneName, () => {
            this._sceneName = sceneName

            loadArg?.onLoaded && loadArg?.onLoaded()
        })
    }

    public reload(loadArg?: ISceneLoadArg) {
        if (!this._sceneName) {
            cc.error('SceneMgr.reload 未加载过场景')
            return
        }

        this.loadScene(this._sceneName, loadArg)
    }
}
